package com.longcai.cm.base.aspect;

import com.longcai.cm.base.aop.Log;
import com.longcai.cm.common.utils.HttpContextUtils;
import com.longcai.cm.common.utils.IpUtils;
import com.longcai.cm.moudules.system.domain.SysLog;
import com.longcai.cm.moudules.system.service.SysLogService;
import com.longcai.cm.moudules.system.utils.ShiroUtils;
import com.longcai.cm.moudules.system.utils.UUID;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * 定义切面
 *
 * @author chenyue
 * @Description: TODO
 * @file:
 * @throws
 * @date 2018/11/20 15:35
 */
@Aspect
@Component
public class LoggerAspect {

    private static final Logger logger = LoggerFactory.getLogger(LoggerAspect.class);

    @Resource
    public SysLogService sysLogService;

    /**
     * 定义切入点
     */
    @Pointcut("@annotation(com.longcai.cm.base.aop.Log)")
    public void logPointCut() {
    }

    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long beginTime = System.currentTimeMillis();

        String userId = "";
        String userName = "";

        //异步保存日志
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        if ("logOut".equals(method.getName())) {
            userId = ShiroUtils.getUserId();
            userName = ShiroUtils.getUserName();
        }
        //【】 执行方法
        Object result = joinPoint.proceed();

        Log log = method.getAnnotation(Log.class);
        if (log == null) {
            return result;
        }

        if (!"logOut".equals(method.getName())) {
            userId = ShiroUtils.getUserId();
            userName = ShiroUtils.getUserName();
        }
        //【】 记录操作日志
        SysLog sysLog = new SysLog();
        sysLog.setId(UUID.get());

        // 执行时长(毫秒)
        long time = (System.currentTimeMillis() - beginTime) / 1000;

        // 注解上的描述
        sysLog.setOperation(log.value());
        // 请求的方法名
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        sysLog.setMethod(className + "." + methodName + "()");

        // 获取request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        String ip = IpUtils.getIpAddr(request);
        // 设置IP地址
        sysLog.setIp(ip);
        sysLog.setAddress(IpUtils.getCity(ip));
        sysLog.setChannel(1);
        // 执行时间
        sysLog.setTime((int) time);
        sysLog.setUserId(userId);
        sysLog.setUsername(userName);
        // 系统当前时间
        sysLog.setCreateTime(new Date());
        // 保存系统日志
       sysLogService.save(sysLog);

        return result;
    }


    @Before("logPointCut()")
    public void doBeforeAdvice(JoinPoint joinPoint) {
//        System.out.println("进入方法前执行.....");
    }

    /**
     * 处理完请求，返回内容
     *
     * @param ret
     */
    @AfterReturning(returning = "ret", pointcut = "logPointCut()")
    public void doAfterReturning(Object ret) {
//        System.out.println("方法的返回值 : " + ret);
    }

    /**
     * 后置异常通知
     */
    @AfterThrowing("logPointCut()")
    public void throwss(JoinPoint jp) {


    }

    /**
     * 后置最终通知,final增强，不管是抛出异常或者正常退出都会执行
     */
    @After("logPointCut()")
    public void after(JoinPoint jp) {


    }

}
